/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambkit.db.mgr;

import java.io.Serializable;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.List;

import cn.hutool.core.util.StrUtil;
import com.lambkit.db.DbPool;
import com.lambkit.db.IDb;
import com.lambkit.db.dialect.DialectFactory;
import com.lambkit.db.dialect.IDialect;
import com.lambkit.db.meta.ColumnMeta;
import com.lambkit.db.meta.TableMeta;

public class MgrTable implements Serializable {

	private String name;
	private ITable model;
	private TableMeta meta;
	private List<? extends IField> fieldList;

	public IDb db() {
		String configName = meta !=null ? meta.getConfigName() : null;
		return StrUtil.isNotBlank(configName) ? DbPool.use(configName) : DbPool.use();
	}

	public ITable getModel() {
		return model;
	}

	public void setModel(ITable model) {
		this.model = model;
	}

	public TableMeta getMeta() {
		return meta;
	}

	public void setMeta(TableMeta meta) {
		this.meta = meta;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<? extends IField> getFieldList() {
		return fieldList;
	}

	public void setFieldList(List<? extends IField> list) {
		this.fieldList = list;
	}

	public String tableAlias() {
		String alias = model.getAlias();
		if(StrUtil.isBlank(alias)) {
			alias = meta.getAttrName();
		}
		return alias;
	}

	public IField getForeignkey(String fktbname, String fldlinkfk) {
		for (IField iField : fieldList) {
			if(fldlinkfk.equals(iField.getAttr("fldlinkfk"))
			&& fktbname.equals(iField.getAttr("fktbname"))) {
				return iField;
			}
		}
		return null;
	}

	public IField getField(String fieldName) {
		for (IField iField : fieldList) {
			if(iField.getName().equals(fieldName)) {
				return iField;
			}
		}
		return null;
	}

	public IField primaryField() {
		for (IField iField : fieldList) {
			if(iField.getIskey().equals("Y")) {
				return iField;
			}
		}
		return null;
	}

	public int primaryNumber() {
		String primary = getPrimaryKey();
		if(StrUtil.isBlank(primary)) {
			return 0;
		}
		return primary.trim().split(",").length;
	}

	public String primaryAttr() {
		String primary = getPrimaryKey();
		if(StrUtil.isBlank(primary)) {
			return null;
		}
		return StrUtil.toCamelCase(primary);
	}

	/******/
	public String getPrimaryKey() {
		String pkname = null;
		if(meta!=null) {
			pkname = meta.getPrimaryKey();
		}
		if(StrUtil.isBlank(pkname) && model!=null) {
			pkname = model.getPkey();
		}
		return pkname;
	}

	public Object getId() {
		if(model!=null) {
			return model.getId();
		} else {
			return null;
		}
	}

	public String getTitle() {
		if(model!=null) {
			return model.getTitle();
		} else {
			return null;
		}
	}

	public String getConfigName() {
		return meta !=null ? meta.getConfigName() : null;
	}

	public IDialect dialect() {
		if(meta!=null) {
			String dialectName = meta.getDialect();
			return DialectFactory.create(dialectName);
		}
		return null;
	}

//	public void setDialect(IDialect dialect) {
//		this.dialect = dialect;
//	}

	public boolean hasColumn(String fldName) {
		if(StrUtil.isBlank(fldName)) {
			return false;
		}
		if(fieldList!=null) {
			for (IField iField : fieldList) {
				if(fldName.equals(iField.getName())) {
					return true;
				}
			}
		} else if(meta!=null && meta.getColumnMetas()!=null) {
			for (ColumnMeta column : meta.getColumnMetas()) {
				if(fldName.equals(column.getName())) {
					return true;
				}
			}
		}
		return false;
	}

	public Object getValue(String type, String value) {
		type = type.toLowerCase();
		if(type.startsWith("int") || type.startsWith("serial")) {
			return Integer.parseInt(value);
		}
		else if(type.startsWith("float")) {
			return Float.parseFloat(value);
		}
		else if(type.startsWith("double")) {
			return Double.parseDouble(value);
		}
		else if(type.startsWith("num")) {
			return Double.parseDouble(value);//numeric,number
		}
		else if(type.startsWith("date")) {
			return Date.valueOf(value);
		}
		else if(type.startsWith("datetime")) {
			return Timestamp.valueOf(value);
		}
		else if(type.startsWith("timestamp")) {
			return Timestamp.valueOf(value);
		}
		else {
			return value;
		}
	}

	public String getSelectNamesOfView(String alias) {
		String fldAlias = StrUtil.isBlank(alias) ? "" : alias+".";
		StringBuilder strb = new StringBuilder();
		for(IField field : fieldList) {
			if(!field.getIsselect().equals("N")) {
				strb.append(fldAlias).append(field.getName()).append(",");
			}
		}
		return strb.substring(0, strb.length()-1);
	}

    public String getLoadColumns(String alias) {
		return getSelectNamesOfView(alias);
    }
    /////////////////////////////////////////////////

//	public String getLoadColumns(String alias) {
//		return MgrdbManager.me().getService().getSelectNamesOfView(this, alias);
//	}

//	protected String sql4FindById(Object id) {
//		String pkname = getPrimaryKey();
//		IDialect dialect = dialect();
//		return dialect!=null ? dialect.forFindByColumns(getName(), getLoadColumns(""), Columns.create(pkname, id), "", null) : null;
//	}
}
